#ifndef XL_UPLOADER_DLG_ABOUT_H
#define XL_UPLOADER_DLG_ABOUT_H
#include <atlstr.h>
#include <atltypes.h>
#include <atlbase.h>
#include <atlapp.h>
#include <atlwin.h>
#include <atlctrls.h>
#include <atldlgs.h>
#include "Language.h"
#include "version.h"

extern CAppModule _Module;

typedef CWinTraits<
	WS_VISIBLE | WS_POPUP | WS_CLIPCHILDREN | WS_CAPTION | WS_SYSMENU | DS_CENTER,
	0
	> CDlgAboutTraits;

class CDlgAbout
	: public CIndirectDialogImpl<CDlgAbout, CMemDlgTemplate>
{
	HICON m_hBigIcon;
	HICON m_hIcon;

	CButton m_buttonOk;
	CStatic m_logo;
	CStatic m_hr;
	CStatic m_vr;

	enum _LABEL_ID {
		LABEL_COPYRIGHT,
		LABEL_PROGRAMMER,
		LABEL_OURSITE,
		LABEL_LICENSE,
		LABEL_DONATE,
		LABEL_THANKS,
		LABEL_COUNT,
		LABEL_THANKS_1 = LABEL_COUNT,
		LABEL_THANKS_2,
		LABEL_LINKS_COUNT
	};
	CTransparentStatic m_labels[LABEL_COUNT];
	CHyperLink m_hypers[LABEL_LINKS_COUNT];
	CTransparentStatic m_version;

	static const int MARGINX = 10;
	static const int MARGINY = 5;
	static const int PADDING = 2;
	static const int LABEL_WIDTH = 140;
	static const int IMAGE_WIDTH = 256;
	static const int IMAGE_HEIGHT = 256;
	static const int BUTTON_HEIGHT = 28;
	static const int LINE_SIZE = 2;
	static const int CLIENT_X = MARGINX + IMAGE_WIDTH + MARGINX + LINE_SIZE + MARGINX + LABEL_WIDTH + MARGINX;
	static const int CLIENT_Y = MARGINY + LABEL_LINKS_COUNT * 0/* calc in runtime*/ 
		+ MARGINY + LINE_SIZE + MARGINY + BUTTON_HEIGHT + MARGINY;

	void _CreateLabels() {
		CRect rc;
		GetClientRect(&rc);
		CLanguage *pLanguage = CLanguage::getInstance();

		// titles
		static const tstring titles[LABEL_COUNT] = {
			pLanguage->getString(_T("Programmer & Designer:")),
			pLanguage->getString(_T("Copyright:")),
			pLanguage->getString(_T("Source code:")),
			pLanguage->getString(_T("License:")),
			pLanguage->getString(_T("Donation:")),
			pLanguage->getString(_T("Thanks to:")),
		};
		static const TCHAR *hyperTitles[LABEL_LINKS_COUNT] = {
			_T("cyberscorpio@gmail.com"),
			_T("xilou / software"),
			_T("Google Code"),
			_T("New BSD License"),
			_T("Support us"),
			_T("libcurl (HTTP)"),
			_T("htmlcxx (HTML)"),
			_T("pcre (regex)"),
		};
		static const TCHAR *hyperLinks[LABEL_LINKS_COUNT] = {
			_T("mailto:cyberscorpio@gmail.com"),
			_T("http://www.xilou.us"),
			_T("http://code.google.com/p/xl-uploader/"),
			_T("http://www.opensource.org/licenses/bsd-license.php"),
			_T("https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=10694914"),
			_T("http://curl.haxx.se/"),
			_T("http://htmlcxx.sourceforge.net/"),
			_T("http://www.pcre.org/"),
		};

		// get line height
		int height = PADDING * 2;
		HFONT font = (HFONT)::GetStockObject(DEFAULT_GUI_FONT);
		LOGFONT lf;
		::GetObject(font, sizeof(lf), &lf);
		height += (lf.lfHeight > 0 ? lf.lfHeight : -lf.lfHeight);

		rc.right -= MARGINX;
		rc.left = rc.right - LABEL_WIDTH;
		rc.top += MARGINY + MARGINX;
		DWORD dwStyle = WS_CHILD | WS_VISIBLE;
		int i = 0;
		for (; i < (int)LABEL_LINKS_COUNT; ++ i) {
			// label
			if (i < (int)LABEL_COUNT) {
				rc.bottom = rc.top + height;
				m_labels[i].Create(m_hWnd, rc, titles[i].c_str(), dwStyle);
				m_labels[i].SetFont(font);
				rc.top = rc.bottom + 1;

				// link
				rc.bottom = rc.top + height;
				m_hypers[i].Create(m_hWnd, rc, hyperTitles[i], dwStyle);
				m_hypers[i].SetFont(font);
				m_hypers[i].setLink(hyperLinks[i]);
				rc.top = rc.bottom + MARGINY;
			} else {
				// additional links
				rc.top -= (MARGINY - 1);
				rc.bottom = rc.top + height;
				m_hypers[i].Create(m_hWnd, rc, hyperTitles[i], dwStyle);
				m_hypers[i].SetFont(font);
				m_hypers[i].setLink(hyperLinks[i]);
				rc.top = rc.bottom + MARGINY;
			}

		}

		// version
		ATLASSERT (::IsWindow(m_logo.m_hWnd));
		m_logo.GetWindowRect(rc);
		ScreenToClient(rc);
		// rc.top = rc.top + (rc.Height() - height) / 2;
		rc.top = rc.bottom - height / 2;
		rc.bottom = rc.top + height;
		m_version.setAlign(CTransparentStatic::CENTER);
		tstring version = pLanguage->getString(_T("Version:"));
		version += _T(" 1.0.");
		version += xl_revision;
		m_version.Create(m_hWnd, rc, version.c_str(), dwStyle);
		m_version.SetFont(font);
		m_version.SetWindowPos(HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
	}

public:
	CDlgAbout(void) {
		m_hIcon = ::LoadIcon(_Module.get_m_hInst(), MAKEINTRESOURCE(IDI_MAINICON));
		m_hBigIcon = (HICON)::LoadImage(_Module.get_m_hInst(), MAKEINTRESOURCE(IDI_MAINICON), IMAGE_ICON, 256, 256, 0);

		for (int i = 0; i < (int)LABEL_LINKS_COUNT; ++ i) {
			if (i < (int)LABEL_COUNT) {
				m_labels[i].setSibling(this);
				m_labels[i].setAlign(CTransparentStatic::LEFT);
			}
			m_hypers[i].setSibling(this);
			m_hypers[i].setAlign(CTransparentStatic::RIGHT);
		}
		m_version.setSibling(&m_logo);
	}
	virtual ~CDlgAbout(void) {
		if (m_hIcon) {
			::DestroyIcon(m_hIcon);
		}
		if (m_hBigIcon) {
			::DestroyIcon(m_hBigIcon);
		}
	}

public:
	//override the DoInitTemplate and set the correct values for template
	void DoInitTemplate()
	{
		CLanguage *pLanguage = CLanguage::getInstance();
		m_Template.Create(
			false,
			pLanguage->getString(_T("About:")).c_str(),
			0, 0, 0, 0,
			CDlgAboutTraits::GetWndStyle(0),
			CDlgAboutTraits::GetWndExStyle(0)
			);
	}

	void DoInitControls() {
	}

	BEGIN_MSG_MAP(CDlgAbout)
		MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
		MESSAGE_HANDLER(WM_SYSCOMMAND, OnSysCommand)
		MESSAGE_HANDLER(WM_KEYDOWN, OnKeyDown)
		COMMAND_ID_HANDLER(IDOK, OnCmdOk)
		COMMAND_ID_HANDLER(IDCANCEL, OnCmdCancel)
	END_MSG_MAP()

	LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL &bHandled)
	{
		CLanguage *pLanguage = CLanguage::getInstance();
		HFONT hFont = (HFONT)::GetStockObject(DEFAULT_GUI_FONT);

		SetClassLong(m_hWnd, GCL_HICON, (LONG)m_hIcon);
		SetClassLong(m_hWnd, GCL_HICONSM, (LONG)m_hIcon);

		CWindow wndParent = GetParent();
		CRect rcParent;
		wndParent.GetWindowRect(rcParent);
		int staticHeight = PADDING * 2;
		HFONT font = (HFONT)::GetStockObject(DEFAULT_GUI_FONT);
		LOGFONT lf;
		::GetObject(font, sizeof(lf), &lf);
		staticHeight += (lf.lfHeight > 0 ? lf.lfHeight : -lf.lfHeight);

		int w = CLIENT_X;
		int h = CLIENT_Y + LABEL_LINKS_COUNT * (staticHeight + 1 + staticHeight + MARGINY)
			- (LABEL_LINKS_COUNT - LABEL_COUNT) * staticHeight;
		// Adjust window size
		CRect rcWindow(0, 0, w, h);
		ClientToScreen(rcWindow);
		AdjustWindowRect(rcWindow, GetStyle(), FALSE);
		w = rcWindow.Width();
		h = rcWindow.Height();

		int x = rcParent.left + (rcParent.Width() - w) / 2;
		int y = rcParent.top + (rcParent.Height() - h) / 2;
		SetWindowPos(0, x, y, w, h, SWP_NOZORDER);

		// Create children
		CRect rcClient, rc;
		DWORD dwStyle = WS_CHILD | WS_VISIBLE;
		GetClientRect(rcClient);

		// logo
		rc = rcClient;
		x = MARGINX;
		y = (rcClient.Height() - IMAGE_HEIGHT - MARGINY - BUTTON_HEIGHT - MARGINY - LINE_SIZE) / 2;
		w = IMAGE_WIDTH;
		h = IMAGE_HEIGHT;
		rc.left = x;
		rc.top = y;
		m_logo.Create(m_hWnd, rc, _T(""),
			dwStyle | SS_ICON | SS_REALSIZEIMAGE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, 
			0);
		m_logo.SetIcon(m_hBigIcon);

		// close button
		rc = rcClient;
		rc.bottom -= MARGINY;
		rc.top = rc.bottom - BUTTON_HEIGHT;
		rc.left = (rc.Width() - 120) / 2;
		rc.right = rc.left + 120;
		m_buttonOk.Create(m_hWnd, rc, pLanguage->getString(_T("Close")).c_str(), dwStyle, 0, IDOK);
		m_buttonOk.SetFont(hFont);

		// <hr />
		rc.top -= (MARGINY + LINE_SIZE);
		rc.bottom = rc.top + LINE_SIZE;
		rc.left = rcClient.left + MARGINX;
		rc.right = rcClient.right - MARGINX;
		m_hr.Create(m_hWnd, rc, _T(""), dwStyle | SS_SUNKEN);

		// vr
#if 0
		rc.top = rcClient.top + MARGINY;
		rc.bottom -= 2;//MARGINY;
		rc.right = rcClient.right - MARGINX * 2 - LABEL_WIDTH;
		rc.left = rc.right - LINE_SIZE;
		m_vr.Create(m_hWnd, rc, _T(""), dwStyle | SS_SUNKEN);
#endif

		// labels
		_CreateLabels();

		return bHandled = FALSE;
	}

	LRESULT OnSysCommand(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL &bHandled) {
		if (wParam != SC_CLOSE) {
			bHandled = false;
			return 0;
		}

		EndDialog(IDOK);
		return 0;
	}

	LRESULT OnCmdOk(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled) {
		EndDialog(IDOK);
		return 0;
	}

	LRESULT OnCmdCancel(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled) {
		EndDialog(IDCANCEL);
		return 0;
	}

	LRESULT OnKeyDown(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL &bHandled) {
		wchar_t wc = (wchar_t)wParam;
		if (wc == 0x0A || wc == 0x0D) { // enter
			EndDialog(IDOK);
		}
		return 0;
	}
};

#endif
